package com.chatplus.application.service.pay.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;
import com.chatplus.application.client.pay.AliPayClient;
import com.chatplus.application.client.pay.domain.request.alipay.AlipayOrderPayRequest;
import com.chatplus.application.client.pay.domain.response.InternalPayQueryResponse;
import com.chatplus.application.client.pay.domain.response.InternalPayResponse;
import com.chatplus.application.client.pay.domain.response.alipay.AlipayOrderPayResponse;
import com.chatplus.application.common.exception.BadRequestException;
import com.chatplus.application.common.logging.SouthernQuietLogger;
import com.chatplus.application.common.logging.SouthernQuietLoggerFactory;
import com.chatplus.application.constant.PayConstants;
import com.chatplus.application.domain.entity.pay.PayRequestEntity;
import com.chatplus.application.enumeration.PayChannelEnum;
import com.chatplus.application.enumeration.PayStatusEnum;
import com.chatplus.application.service.pay.PayChannelServiceProvider;
import com.chatplus.application.service.pay.impl.alipay.AliPayApiService;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.Map;

/**
 * 支付渠道业务逻辑实现（支付宝）
 */
@Service(PayChannelServiceProvider.SERVICE_NAME_PRE + "ALIPAY")
public class AliPayChannelServiceImpl extends PayChannelService {

    private static final SouthernQuietLogger LOGGER = SouthernQuietLoggerFactory.getLogger(AliPayChannelServiceImpl.class);

    private final AliPayClient aliPayServiceClient;

    private final AliPayApiService aliPayApiService;

    public AliPayChannelServiceImpl(AliPayClient aliPayServiceClient, AliPayApiService aliPayApiService) {
        this.aliPayServiceClient = aliPayServiceClient;
        this.aliPayApiService = aliPayApiService;
    }

    @Override
    public InternalPayResponse orderPay(PayRequestEntity payRequestEntity, String subject) {
        InternalPayResponse paymentPayResponse = new InternalPayResponse();
        AlipayOrderPayRequest alipayOrderPayRequest = AlipayOrderPayRequest.build();
        alipayOrderPayRequest.setRequired(payRequestEntity.getTotalMoney(), payRequestEntity.getPayTransactionId() + "", subject);
        AlipayOrderPayResponse alipayOrderPayResponse = aliPayApiService.orderPay(alipayOrderPayRequest);
        if (alipayOrderPayResponse == null) {
            throw new BadRequestException("支付宝支付失败-请联系管理员处理");
        }
        paymentPayResponse.setActionUrl(alipayOrderPayResponse.getActionUrl());
        LOGGER.message("支付宝返回")
                .context("actionUrl", alipayOrderPayResponse.getActionUrl())
                .info();
        payRequestEntity.setAppId(alipayOrderPayResponse.getAppId());
        payRequestEntity.setErrCode(alipayOrderPayResponse.getResponseCode());
        payRequestEntity.setErrCodeDes(alipayOrderPayResponse.getResponseMsg());
        return paymentPayResponse;
    }

    @Override
    public InternalPayQueryResponse queryOrderPay(PayRequestEntity payRequestEntity) {
        AlipayTradeQueryResponse aliYunResult = aliPayApiService.queryOrderPay(payRequestEntity);
        if (ResponseChecker.success(aliYunResult)) {
            InternalPayQueryResponse queryOrderPayResponse = new InternalPayQueryResponse();
            String tradeStatus = aliYunResult.getTradeStatus();
            switch (tradeStatus) {
                case PayConstants.Alipay.TRADE_SUCCESS:
                    Instant payTime = ObjectUtil.defaultIfEmpty(aliYunResult.sendPayDate,
                            () -> DateUtil.parse(aliYunResult.sendPayDate,
                                    DatePattern.NORM_DATETIME_PATTERN).toInstant(), Instant.now());
                    queryOrderPayResponse.setPaySuccessAt(payTime);
                    queryOrderPayResponse.setPayStatusEnum(PayStatusEnum.SUCCESS);
                    queryOrderPayResponse.setPayerInfo(aliYunResult.getBuyerUserId());
                    queryOrderPayResponse.setTradeTransactionId(aliYunResult.getTradeNo());
                    queryOrderPayResponse.setPayerInfo(aliYunResult.getBuyerUserId() + "|" + aliYunResult.getBuyerLogonId());
                    break;
                // 如果交易关闭|结束，不处理支付结果，但是不报错，消费掉队列消息
                case PayConstants.Alipay.TRADE_CLOSED:
                case PayConstants.Alipay.TRADE_FINISHED:// 订单未支付，超时关闭订单
                    queryOrderPayResponse.setPayerInfo(aliYunResult.getBuyerUserId());
                    queryOrderPayResponse.setPayStatusEnum(PayStatusEnum.FAIL);
                    break;
                default:
                    break;
            }
            return queryOrderPayResponse;
        }
        return null;
    }

    @Override
    public boolean verifySign(Map<String, String> params) {
        try {
            return aliPayServiceClient.verifySign(params);
        } catch (Exception e) {
            LOGGER.message("支付宝支付-支付宝回调验签失败").context("params", params).exception(e).error();
        }
        return false;
    }

    @Override
    public PayChannelEnum getChannel() {
        return PayChannelEnum.ALIPAY;
    }

    @Override
    public String getLogo() {
        return "/img/alipay.jpg";
    }
}
